from regex import E
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC  # 导入条件
from selenium.webdriver.common.by import By  # 选择
from chaojiying import Chaojiying  # 导入接码
import logging  # 日志记录
import time  # 导入时间
from selenium.webdriver.common.action_chains import ActionChains  # 导入动作链
from PIL import Image  # 导入图像处理库
from io import BytesIO  # 用于二进制的读写


logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(levelname)s: %(message)s')

username = 'Cthousand'  # 用户名
password = input('password:')  # 密码
soft_id = '931779'  # 软件ID
captcha_kind = '9004'  # 验证码类型

client = Chaojiying(username=username, password=password,
                    soft_id=soft_id)  # 创建一个接码实例
browser = webdriver.Chrome()  # 实例化浏览器

# 压缩验证码图片，w:460 h:310，返回二进制图片和压缩比例


def Compress(im):
    im = Image.open(BytesIO(im))  # 将网络字节流以二进制形式传递进来生成im对象
    width, height = im.size  # 获取宽度和高度
    logging.info(f'宽度:{width},高度:{height}')
    standard_rate = 460/310  # 接码平台图片尺寸限制
    # 如果宽高比大于标准体，且宽和高至少一项超过标准
    if width/height > standard_rate and (width > 460 or height > 310):
        im1 = im.resize(
            (int(width/width*460), int(height/width*460)))  # 以宽为主要压缩图片
    else:
        im1 = im.resize(
            (int(width/height*310), int(height/height*310)))  # 以高为主要压缩图片
    img_bytes = BytesIO()  # 创建二进制读写通道
    im1.save(img_bytes, format='PNG')  # 将im对象以png格式转化成二进制存在通道里
    binary_str = img_bytes.getvalue()  # 从通道中提取二进制字节流
    return [binary_str, height/im1.size[1]]  # 返回一个列表，包括图片二进制，压缩比(传递浏览器坐标时需要)

# 登录


def login():
    browser.get('https://captcha6.scrape.center/')  # 向服务器发送url请求
    time.sleep(1)
    browser.find_element(
        by=By.CSS_SELECTOR, value='input[type="text"]').send_keys('admin')  # 用户名输入
    browser.find_element(
        by=By.CSS_SELECTOR, value='input[type="password"]').send_keys('admin')  # 密码输入
    # 点击点击时灵时不灵，可能是网站的问题
    for i in range(100):
        try:
            login = browser.find_element(by=By.XPATH,
                                         value='//span[contains(text(),"登录")]')
            print(login.text)
            login.click()
            time.sleep(1)  # 没隔一秒点击一次登录
        except:
            break  # 如果找不到登录元素就跳出循环
    try:
        WebDriverWait(browser, 10).until(EC.presence_of_element_located(
            (By.XPATH, '//div[contains(text(),"确认")]')))  # 等待页面加载
    except:
        logging.error('超时！')
    captcha = browser.find_element(
        by=By.CSS_SELECTOR, value='div.geetest_widget')  # 定位到验证码图片
    captcha_png_ba64 = captcha.screenshot_as_png  # 获取截图二进制
    captchaCompress = Compress(captcha_png_ba64)  # 调用压缩方法压缩图片
    logging.info(f'发送验证码中..')
    captcha_result = client.post_pic(   # 向接码平台发送验证码和图片类型
        captchaCompress[0], captcha_kind)
    logging.info(f'captcha:{captcha_result}')  # 输出接码结果
    # 提取坐标
    captcha1 = captcha_result['pic_str'].split('|')
    for i in captcha1:
        x = i.split(',')[0]
        y = i.split(',')[1]
        logging.info(f'坐标：{(x, y)}')
        ActionChains(browser).move_to_element_with_offset(  # 动作链执行一下
            captcha, int(float(x)*captchaCompress[1]), int(float(y)*captchaCompress[1])).click().perform()    # 注意要用perform执行一下
        time.sleep(1)
    browser.find_element(
        by=By.XPATH, value='//div[contains(text(),"确认")]').click()  # 找到确认按钮并点击
    time.sleep(2)  # 等待2s
    # 验证是否正确
    try:
        browser.find_element(
            by=By.XPATH, value='//div[contains(text(),"确认")]').click()  # 再次点击一下，如果没有跳转，说明验证失败
        client.report_error(captcha_result['pic_id'])  # 上传错误验证码图片id给接码平台
        print('登录失败')
    except:
        logging.info('success login!')
    time.sleep(5)
    browser.close()


if __name__ == '__main__':
    login()
